package Thread.Thread_Security;

public class Demo29 {
    //通过wait和notify来顺序打印 A B C可以避免线程的无序执行

    public static Object locker1 = new Object();
    public static Object locker2 = new Object();
    public static Object locker3 = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(()->{
            for (int i = 0; i < 10; i++) {
                synchronized (locker3) {
                    try {
                        locker3.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.print("A");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (locker1){
                    locker1.notify();
                }
            }
        });
        //但是这种状况下有极小的概率t1线程中会一次性执行了打印和notify，
        // 这样t2后执行的wait就永远不会收到通知了，这样线程就会死掉
        /*为了避免这样的小概率事件发生，我们在t1线程执行完打印之后
        加一个sleep给出t2线程足够的时间先执行wait操作即可*/
         Thread t2=new Thread(()->{
            for (int i = 0; i < 10; i++) {
                synchronized (locker1){
                    try {
                        locker1.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.print("B");
                synchronized (locker2){
                    locker2.notify();
                }
            }

        });
        Thread t3=new Thread(()->{
            for (int i = 0; i < 10; i++) {
                synchronized (locker2){
                    try {
                        locker2.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("C");
                synchronized (locker3){
                    locker3.notify();
                }
            }

        });

        t1.start();
        t2.start();
        t3.start();
        //在主线程加一个sleep确保所有的线程均进入了等待状态
        Thread.sleep(100);

        //主线程去唤醒t1线程
        synchronized (locker3){
            locker3.notify();
        }
    }
}
